import path from 'node:path'
import chalk from 'chalk'
import figlet from 'figlet'
import fs from 'fs-extra'
import inquirer from 'inquirer'

// eslint-disable-next-line node/prefer-global/process
const projectRoot = process.cwd()

function displayWelcomeMessage() {
  console.log(chalk.green(figlet.textSync('create app', { horizontalLayout: 'full' })))
}

async function updatePackageJson(appName: string) {
  try {
    const packageJsonPath = path.join(projectRoot, 'apps', appName, 'package.json')
    const packageJson = await fs.readJson(packageJsonPath)

    packageJson.name = `@apps/${appName}`

    await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 })
    console.log(chalk.green(`2 package.json name已更新: ${packageJson.name}`))
  }
  catch (error) {
    console.error(`package.json 更新失败>>>>${error}`)
  }
}

async function updateViteConfig(appName: string) {
  try {
    const viteConfigPath = path.join(projectRoot, 'apps', appName, 'vite.config.ts')
    let viteConfigContent = await fs.readFile(viteConfigPath, 'utf-8')

    viteConfigContent = viteConfigContent.replace(/'@apps\/demo'/g, `'@apps/${appName}'`)

    await fs.writeFile(viteConfigPath, viteConfigContent)
    console.log(chalk.green(`3 vite.config.ts已更新，alias: '@apps/demo' -> '@apps/${appName}'`))
  }
  catch (error) {
    console.error(`vite.config.ts 更新失败>>>>${error}`)
  }
}

async function updateTsConfig(appName: string) {
  try {
    const tsConfigPath = path.join(projectRoot, 'tsconfig.json')

    const tsConfig = await fs.readJson(tsConfigPath)

    const newPath = `apps/${appName}/*`
    const newAlias = `@${appName}/*`

    if (!tsConfig.compilerOptions.paths) {
      tsConfig.compilerOptions.paths = {}
    }

    tsConfig.compilerOptions.paths[newAlias] = [newPath]

    await fs.writeJson(tsConfigPath, tsConfig, { spaces: 2 })

    console.log(chalk.green(`4 tsconfig.json已更新,添加路径: ${newAlias} -> ${newPath}`))
  }
  catch (err) {
    console.error(chalk.red('tsconfig.json 更新失败:', err))
  }
}

async function createApp() {
  const answers = await inquirer.prompt([
    {
      type: 'input',
      name: 'appName',
      message: chalk.blue('请输入应用名(英文小写):'),
      validate: (input) => {
        const chineseRegex = /[\u4E00-\u9FA5]/
        if (chineseRegex.test(input)) {
          return '应用名不能包含中文字符，请重新输入'
        }
        return true
      },
    },
  ])

  const { appName } = answers

  const templateDir = path.join(projectRoot, 'scripts/create-app/_template')
  const newAppDir = path.join(projectRoot, 'apps', appName)

  if (fs.existsSync(newAppDir)) {
    console.error(chalk.red(`应用名 ${appName} 已存在，请选择其他应用名`))
    return
  }

  try {
    await fs.copy(templateDir, newAppDir)
    console.log(chalk.green(`1 子应用${appName}已成功创建在 ${newAppDir}`))

    return appName
  }
  catch (err) {
    console.error(chalk.red('创建应用出错了:', err))
  }
}

async function main() {
  try {
    displayWelcomeMessage()

    const appName = await createApp()

    if (appName) {
      await updatePackageJson(appName)
      await updateViteConfig(appName)
      await updateTsConfig(appName)
    }
  }
  catch (err) {
    console.error(chalk.red('出错了:', err))
  }
}

main()
